package com.gmail.viktor.yuryev.strategy;

import com.gmail.viktor.yuryev.model.ServerDetails;
import com.jcraft.jsch.*;

import java.io.File;
import java.io.InputStream;

/**
 * Created by Viktor Yuryev on 4/7/2014.
 */
public abstract class AbstractUploadStrategy {

    protected final Session session;
    protected ChannelSftp sftp;

    public AbstractUploadStrategy(Session session) {
        this.session = session;
    }

    public void upload(String srcFile, String destDir) throws Exception {
        connect();
        File file = new File(srcFile);
        prepareFilesToUpload();
        uploadInternal(file, destDir);
        unzip(file, destDir);
        disconnectAndReleaseResources();

    }

    private void unzip(File srcFile, String destDir) throws Exception {
        execCmdReturnScreenOutput("cd " + destDir + "; unzip " + srcFile.getName());
        execCmdReturnScreenOutput("rm -rf " + srcFile.getName());
    }

    private void prepareFilesToUpload() {

    }

    protected void connect() throws JSchException {
        sftp = (ChannelSftp) session.openChannel("sftp");
        sftp.connect();
    }


    protected abstract void uploadInternal(File srcFile, String destDir) throws Exception;

    protected void disconnectAndReleaseResources() throws JSchException {
        sftp.disconnect();
    }

    public StringBuffer execCmdReturnScreenOutput(String cmd)
            throws Exception {
        StringBuffer buf = new StringBuffer();

        Channel channel = session.openChannel("exec");
        String command = getCommand(cmd);
        ((ChannelExec) channel).setCommand(command);
        ((ChannelExec) channel).setErrStream(System.err);

        channel.connect();
        InputStream in = channel.getInputStream();
        // don't disconnect too early!
        byte[] tmp = new byte[1024];
        while (true) {
            while (in.available() > 0) {
                int i = in.read(tmp, 0, 1024);
                if (i < 0)
                    break;
                buf.append(new String(tmp, 0, i));
            }
            if (channel.isClosed()) {
                System.out.println("exit-status: " + channel.getExitStatus());
                break;
            }
            Thread.sleep(1000);
        }
        System.out.println("executed command: " + command);
        channel.disconnect();

        return buf;
    }

    protected abstract String getCommand(String cmd);



    public static AbstractUploadStrategy resolve(Session session, ServerDetails serverDetails) {
        if (serverDetails.getSudoPrefix() != null) {
            return new SudoStrategy(session, serverDetails);
        } else
            return new SimpleStrategy(session);
    }


}
